package com.iwhalecloud.bss.kite.cucc.service.pos.handler.impl;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.google.common.collect.Lists;
import com.iwhalecloud.bss.kite.common.constant.KeyConsts;
import com.iwhalecloud.bss.kite.common.util.KiteListUtils;
import com.iwhalecloud.bss.kite.common.util.KiteStringUtils;
import com.iwhalecloud.bss.kite.cucc.client.dto.batch.KiteBatchAcceptDetailDTO;
import com.iwhalecloud.bss.kite.cucc.client.dto.pos.KitePosAccountDTO;
import com.iwhalecloud.bss.kite.cucc.client.dto.pos.KitePosContractDTO;
import com.iwhalecloud.bss.kite.cucc.client.dto.pos.KitePosDiscountDTO;
import com.iwhalecloud.bss.kite.cucc.client.dto.pos.KitePosGoodsDTO;
import com.iwhalecloud.bss.kite.cucc.dataservice.mapper.batch.KiteBatchAcceptDetailMapper;
import com.iwhalecloud.bss.kite.cucc.service.pos.handler.CuccPosServiceUtils;
import com.iwhalecloud.bss.kite.cucc.service.pos.handler.IKitePosSceneHandler;
import com.iwhalecloud.bss.kite.cucc.service.pos.handler.KitePosHandlerContext;
import com.iwhalecloud.bss.kite.manager.api.IQuerySceneInstService;

/**
 * @author lyx
 * @version V1.0
 * @Description: 批量受理收单报文特殊处理：除了goods、users节点，其他节点传单个
 * @date 2022/1/7 0007
 */
@Service
public class KitePosBatchAcceptHandler implements IKitePosSceneHandler {

    @Autowired
    private IQuerySceneInstService querySceneInstService;

    @Autowired
    private KiteBatchAcceptDetailMapper batchAcceptDetailMapper;

    @Override
    public void handle(KitePosHandlerContext context) {
        if (!CuccPosServiceUtils.isBatchAccept(context.getSceneInstId())) {
            return;
        }
        List<KitePosGoodsDTO> posGoodsList = context.getPosDto().getGoods();
        // 合同 同一个合同编号只要一条
        List<KitePosContractDTO> contractList = context.getPosDto().getContract();
        Map<String, KitePosContractDTO> contractMap = new HashMap<>();
        if (KiteListUtils.isNotEmpty(contractList)) {
            contractList.forEach(contract -> {
                if (contractMap.containsKey(contract.getContractCode())) {
                    return;
                }
                contractMap.put(contract.getContractCode(), contract);
            });
            context.getPosDto().setContract(Lists.newArrayList(contractMap.values()));
        }
        // 账户 同一个账户id只要一条
        List<KitePosAccountDTO> accountList = context.getPosDto().getAccounts();
        Map<String, KitePosAccountDTO> accountMap = new HashMap<>();
        if (KiteListUtils.isNotEmpty(accountList)) {
            accountList.forEach(account -> {
                if (accountMap.containsKey(account.getAccountId())) {
                    return;
                }
                accountMap.put(account.getAccountId(), account);
            });
            context.getPosDto().setAccounts(Lists.newArrayList(accountMap.values()));
        }
        // 折扣
        List<KitePosDiscountDTO> discountList = context.getPosDto().getDiscount();
        if (KiteListUtils.isNotEmpty(discountList)) {
            KitePosDiscountDTO discountDTO = discountList.get(0);
            context.getPosDto().setDiscount(Lists.newArrayList(discountDTO));
        }

        // 失败重提
        String failRecommit = this.querySceneInstService.getExtParameterValue(context.getSceneInstId(), "failRecommit");
        Boolean failRecommitRoot = this.querySceneInstService.getExtParameterValue(context.getSceneInstId(), "failRecommitRoot");
        System.out.println("KitePosBatchAcceptHandler，failRecommit，failRecommitRoot==" + failRecommit + "," + failRecommitRoot);
        if (KiteStringUtils.equals(failRecommit, KeyConsts.IFTRUE_T)) {
            // 如果是重提场景，根据offerInstId过滤掉非当前重提记录的节点
            List<KiteBatchAcceptDetailDTO> executeDetails =
                this.querySceneInstService.getExtParameterValue(context.getSceneInstId(), "executeDetails");
            if (KiteListUtils.isNotEmpty(executeDetails)) {
                List<String> executeDetailOfferInsts = executeDetails.stream()
                    .map(detail -> String.valueOf(detail.getOfferInstId())).collect(Collectors.toList());
                posGoodsList.removeIf(goods -> !executeDetailOfferInsts.contains(goods.getInstanceId()));
                List<String> goodsUserInstId = posGoodsList.stream()
                    .map(KitePosGoodsDTO::getUserInstId).collect(Collectors.toList());
                context.getPosDto().getUsers().removeIf(user -> !goodsUserInstId.contains(user.getInstanceId()));

            }
        }

        // 替换goods节点下的实例id
        posGoodsList.forEach(posGoods -> {
            // 折扣审批直接替换
            if (KiteListUtils.isNotEmpty(discountList)) {
                posGoods.setDiscountInstId(discountList.get(0).getInstanceId());
            }
            // 合同根据合同编号找出对应的一条实例
            if (KiteListUtils.isNotEmpty(contractList)) {
                String contractCode = contractList.stream()
                    .filter(contract -> KiteStringUtils.equals(posGoods.getContractInstId(), contract.getInstanceId()))
                    .map(KitePosContractDTO::getContractCode).findFirst().orElse("");
                KitePosContractDTO contractDTO = contractMap.get(contractCode);
                if (Objects.nonNull(contractDTO)) {
                    posGoods.setContractInstId(contractDTO.getInstanceId());
                }
            }
            // 账户、付费关系根据合同编号找出对应的一条实例
            if (KiteListUtils.isNotEmpty(accountList)) {
                String accountId = accountList.stream()
                    .filter(account -> KiteStringUtils.equals(posGoods.getAccountInstId(), account.getInstanceId()))
                    .map(KitePosAccountDTO::getAccountId).findFirst().orElse("");
                KitePosAccountDTO accountDTO = accountMap.get(accountId);
                if (Objects.nonNull(accountDTO)) {
                    posGoods.setAccountInstId(accountDTO.getInstanceId());
                }
                posGoods.getPayRelation().forEach(payRel -> {
                    String payAccountId = accountList.stream()
                        .filter(account -> KiteStringUtils.equals(payRel.getAccountInstId(), account.getInstanceId()))
                        .map(KitePosAccountDTO::getAccountId).findFirst().orElse("");
                    KitePosAccountDTO payAccountDTO = accountMap.get(payAccountId);
                    if (Objects.nonNull(payAccountDTO)) {
                        payRel.setAccountInstId(payAccountDTO.getInstanceId());
                    }
                });
            }
        });
    }
}
